/*
    ts中的类型:
        number，任意数字，比如1,2,3
        string，任意字符串，比如"hello world"
        boolean，布尔值，比如true,false
        字面量，其本身，限制变量的值就是该字面量的值
        any，任意类型
        unknown，类型安全的any
        void，空值或undefined
        never，没有值，不能是任何值
        object，任意的js对象，比如{name:'hzj'};
        array，任意的js数组，比如[1,2,3]
        tuple，元素，ts新增类型，也就是固定长度的数组
        enum，枚举类型，ts新增类型，例如enum{A,B};
    除了前三种类型，后面的可能你一时无法理解，别急，听我娓娓道来
*/

// object表示一个js对象, 但是你可曾记得, js中的函数、数组其实都是对象。所以我们开发一般不用
let a:object;
a= {};
a = function(){};//不爆红
a = [];//不爆红

// 不过我们可以利用字面量这样用，就实用多了
// ? 表示这个属性可有可无，就算你不传也不会爆红
let b:{name:string,age?:number};
b = {name:'mks',age:14};

// [propName: string]:any; 表示一个对象中任意类型的属性
let c:{name:string,[propName:string]:any};
c = {name:'zs',age:null,sex:undefined};//这样就行了，对于除name之外的任何属性都不会有限制

/*
    设置函数结构的类型声明:
        语法：(形参1:类型, 形参2:类型,....)=>返回值
*/ 
let d:(num1:number,num2:number)=>number;//这样就是限制了d只能是一个接收两个数值类型参数且返回值也为数值类型的函数

d = function(num1:number,num2:number){
    return num1+num2;
}//这样就不会报错

// 下面这样写就会爆红
// d = function(str:string,num2:number){
//     return str+num2;
// }


/*
    很多时候，我们希望我们的数组里面只能存同一种数据类型的值。我们可以这样限制:
        写法1： let arr:类型[];
        写法2： let arr:Array<类型>;
*/ 
let e1:number[];//e1这个数组只能存放数值类型的数据。
let e2:Array<number>;//这种写法和上面一个意思
e1 = [1,2,3];
// e2 = ['1',2,3];//这样就会爆红

/*
    元组：固定长度的数组。
    有些时候我们希望我们的数组是固定长度的，甚至类型也是按照下标定死的，比如第一个是字符串，第二个是数值。我们可以这样写：

    let arr:[类型1,类型2,类型3,...];
*/ 
let e3:[number,string,number];
e3 = [1,'1',1];//这样没毛病
// e3 = [1,2,3];//第二个值类型不匹配，爆红
// e3 = [1,'2',3,4];//数组长度不匹配，爆红


/*
    enum: 枚举类型
*/ 
enum Gender{
    female = 0,
    male = 1
}
let person:{name:string,gender:Gender};
person = {
    name:'mks',
    gender:Gender.male
}

// 最后就是我们可以自定义类型
type str = string;//这样就把string类型付给了str这个类型，以后直接str就行了。但是这样的一般没啥意义，我们一般不用；

// 那么你就会问了，既然都没意义，为啥还要说。你瞧着，type是这样用的
// 如果未来的开发中，我们可能会遇到这种情况：有很多变量的取值范围是一样的，比如下面这种，都是1 -5 之间的整数，我们就可以这样来指定一个新的类型
type myType = 1 | 2 | 3 |4 |5;
let num1:myType;
num1 = 1;//没毛病
// num2 = 6;//爆红
